package com.coolgor.coldot.service.auth.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.coolgor.xutil.Common.DataTree;
import com.coolgor.xutil.Common.DataTreeNode;
import com.coolgor.coldot.dao.auth.RoleDao;
import com.coolgor.coldot.dto.auth.FunctionExecution;
import com.coolgor.coldot.dto.auth.RoleExecution;
import com.coolgor.coldot.entity.auth.Function;
import com.coolgor.coldot.entity.auth.LocalUser;
import com.coolgor.coldot.entity.auth.Role;
import com.coolgor.coldot.enums.auth.RoleStateEnum;
import com.coolgor.coldot.exceptions.auth.RoleOperationException;
import com.coolgor.coldot.service.auth.FunctionService;
import com.coolgor.coldot.service.auth.RoleService;
import com.coolgor.coldot.common.PageCalculator;

@Service
public class RoleServiceImpl implements RoleService {
	private static Logger log = LoggerFactory.getLogger(RoleServiceImpl.class);

	@Autowired
	private RoleDao roleDao;
	@Autowired
	private FunctionService functionService;

	@Override
	public Role getRole(long roleID) {
		return roleDao.queryRoleById(roleID);
	}

	@Override
	public RoleExecution getRoleList(Role roleCondition, int pageIndex, int pageSize) {
		//将页码转换成行码
		int rowIndex = PageCalculator.calculateRowIndex(pageIndex, pageSize);
		//依据查询条件，调用dao层返回相关的查询结果列表
		List<Role> roleList = roleDao.queryRoleList(roleCondition, rowIndex, pageSize);
		//依据相同的查询条件，返回查询结果总数
		int count = roleDao.queryRoleCount(roleCondition);
		RoleExecution result = new RoleExecution();
		if (roleList != null) {
			result.setState(RoleStateEnum.SUCCESS.getState());
			result.setStateInfo(RoleStateEnum.SUCCESS.getStateInfo());
			result.setRoleList(roleList);
			result.setCount(count);
		} else {
			result.setState(RoleStateEnum.INNER_ERROR.getState());
		}
		return result;
	}

	@Override
	public RoleExecution getRoleListByUser(LocalUser user) {
		// 空值判断
		if (user == null) {
			return new RoleExecution(RoleStateEnum.NULL);
		}
		List<Role> roleList = roleDao.queryRoleListByUserID(user.getUserID());
		if (roleList.size()>0) {
			RoleExecution exe = new RoleExecution(RoleStateEnum.SUCCESS);
			exe.setCount(roleList.size());
			exe.setRoleList(roleList);
			return exe;
		} else {
			return new RoleExecution(RoleStateEnum.NULL);
		}
	}

	@Override
	public RoleExecution getRoleTree(Role rootRole) {
		DataTree roleTree = new DataTree();
		DataTreeNode rootNode = new DataTreeNode();
		int level = 1;
		int numOfNode = 1;
		Role role = roleDao.queryRoleById(rootRole.getRoleID());
		if (role != null) {
			rootNode.setNodeID(Long.toString(role.getRoleID()));
			rootNode.setObject(role);
			rootNode.setLevel(level);
			rootNode.setRoot(true);
		} else {
			return new RoleExecution(RoleStateEnum.NULL);
		}
		List<Long> parentIDList = new ArrayList<Long>();
		parentIDList.add(role.getRoleID());
		List<Role> roleList = roleDao.queryRoleListByParentIDs(parentIDList);
		Map<Long,DataTreeNode> nodeMap1 = new HashMap<Long, DataTreeNode>();
		nodeMap1.put(role.getRoleID(), rootNode);
		Map<Long,DataTreeNode> nodeMap2 ;
		DataTreeNode node ;
		while(roleList.size()>0) {
			level++;
			parentIDList = new ArrayList<Long>();
			nodeMap2 = new HashMap<Long, DataTreeNode>(); 
			for (int i=0; i<roleList.size(); i++) {
				numOfNode++;
				node = new DataTreeNode();
				node.setNodeID(Long.toString(roleList.get(i).getRoleID()));
				node.setObject(roleList.get(i));
				node.setLevel(level);
				node.setRoot(false);
				nodeMap1.get(roleList.get(i).getParentID()).addChild(node);
				nodeMap2.put(roleList.get(i).getRoleID(), node);
				parentIDList.add(roleList.get(i).getRoleID());
			}
			nodeMap1 = nodeMap2;
			roleList = roleDao.queryRoleListByParentIDs(parentIDList);
		}
		roleTree.setRoot(rootNode);
		roleTree.setNumOfNode(numOfNode);
		return new RoleExecution(RoleStateEnum.SUCCESS, roleTree);
	}

	@Override
	public FunctionExecution getFunctionTreeByRole(Function function, Role role) {
		return functionService.getFunctionTreeByRole(function, role);
	}

	@Override
	@Transactional
	public RoleExecution addRole(Role role) throws RoleOperationException {
		// 空值判断
		if (role == null) {
			return new RoleExecution(RoleStateEnum.NULL);
		}
		int effectedNum;
		try {
			// 添加
			effectedNum = roleDao.insert(role);
			if (effectedNum <= 0) {
				throw new RoleOperationException("系统角色添加失败");
			} 
		} catch (Exception e) {
			throw new RoleOperationException("Add Role error:" + e.getMessage());
		}
		return new RoleExecution(RoleStateEnum.SUCCESS, role);
	}

	@Override
	@Transactional
	public RoleExecution modifyRole(Role role) throws RoleOperationException {
		// 空值判断
		if (role == null) {
			return new RoleExecution(RoleStateEnum.NULL);
		}
		int effectedNum;
		// 即将更新信息
		try {
			// 更新操作
			effectedNum = roleDao.update(role);
			if (effectedNum <= 0) {
				throw new RoleOperationException("系统角色信息更新失败");
			} 
		} catch (Exception e) {
			throw new RoleOperationException("Modify Role error:" + e.getMessage());
		}
		return new RoleExecution(RoleStateEnum.SUCCESS, role);
	}

	@Override
	@Transactional
	public RoleExecution removeRole(Role role) throws RoleOperationException {
		// 空值判断
		if (role == null) {
			return new RoleExecution(RoleStateEnum.NULL);
		}
		int effectedNum;
		try {
			// 执行删除操作
			effectedNum = roleDao.delete(role);
			if (effectedNum <= 0) {
				throw new RoleOperationException("系统角色删除失败");
			} 
		} catch (Exception e) {
			throw new RoleOperationException("Delete Role error:" + e.getMessage());
		}
		return new RoleExecution(RoleStateEnum.SUCCESS, role);
	}

	@Override
	@Transactional
	public RoleExecution batchRemoveRole(List<Role> roleList) throws RoleOperationException {
		// 空值判断
		if (roleList == null) {
			return new RoleExecution(RoleStateEnum.NULL);
		}
		List<Long> roleIDList = new ArrayList<Long>();
		for (int i=0; i<roleList.size(); i++) {
			roleIDList.add(roleList.get(i).getRoleID());			
		}
		int effectedNum;
		try {
			// 执行删除操作
			effectedNum = roleDao.deleteBatch(roleIDList);
			if (effectedNum <= 0) {
				throw new RoleOperationException("系统角色信息批量删除失败");
			} 
		} catch (Exception e) {
			throw new RoleOperationException("Delete Function error:" + e.getMessage());
		}
		RoleExecution exe = new RoleExecution(RoleStateEnum.SUCCESS);
		//将删除的记录总数加入到返回值
		exe.setCount(effectedNum);
		return exe;
	}

}
